# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
import subprocess
import time
from threading import Thread
from config_manager import ConfigManager
from logger import setup_logger
import os
from PIL import ImageTk, Image
import psutil
import sys
import pygetwindow as gw

def get_resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, 'resources', relative_path)
    return os.path.join('resources', relative_path)

class TimeControlApp:
    def __init__(self, main_root):
        self.main_root = main_root
        self.root = tk.Toplevel(main_root)
        self.root.tk.call('encoding', 'system', 'utf-8')
        self.root.title("程序运行时间控制器")
        self.root.resizable(False, False)
        self.root.option_add('*Font', ('Microsoft YaHei', 10))
        self.root.protocol('WM_DELETE_WINDOW', self.on_close)

        self.config = ConfigManager()
        self.logger = setup_logger()
        self.create_widgets()
        self.load_programs()

    def create_widgets(self):
        # 程序列表框架
        list_frame = ttk.LabelFrame(self.root, text="受控程序列表")
        list_frame.pack(padx=10, pady=5, fill='both', expand=True)

        # 程序列表树状图
        self.tree = ttk.Treeview(list_frame, columns=('name', 'path', 'time_limit', 'terminate_processes'), show='headings')
        self.tree.heading('name', text='程序名称')
        self.tree.heading('path', text='程序路径')
        self.tree.heading('time_limit', text='允许时长(分钟)')
        self.tree.heading('terminate_processes', text='终止进程')
        self.tree.column('name', anchor='center', width=120)
        self.tree.column('time_limit', anchor='center', width=100)
        self.tree.column('terminate_processes', anchor='center', width=150)
        self.tree.pack(fill='both', expand=True)

        # 控制按钮
        btn_frame = ttk.Frame(list_frame)
        btn_frame.pack(pady=5)
        ttk.Button(btn_frame, text="添加程序", command=self.add_program).pack(side='left', padx=2)
        ttk.Button(btn_frame, text="删除程序", command=self.remove_program).pack(side='left', padx=2)


    def load_programs(self):
        for item in self.tree.get_children():
            self.tree.delete(item)
        for idx, program in enumerate(self.config.get_programs()):
            self.tree.insert('', 'end', values=(
                program['name'], 
                program['path'], 
                program['time_limit'],
                ', '.join(program['terminate_processes'])
            ), iid=str(idx), tags=('center',))

    def add_program(self):
        path = filedialog.askopenfilename(title="选择要控制的程序")
        if path:
            # 新增名称输入对话框
            auto_name = os.path.splitext(os.path.basename(path))[0]
            name = simpledialog.askstring("程序名称", "请输入程序名称（可修改）：", initialvalue=auto_name)
            if not name or name.strip() == '':
                messagebox.showwarning("警告", "程序名称不能为空")
                return
                
            time_limit = simpledialog.askinteger("时间限制", "请输入允许运行时间（分钟）", minvalue=1)
            if time_limit is None:
                return
            
            processes = simpledialog.askstring("终止进程", "请输入需要同时关闭的进程名称（多个用逗号分隔）") or ""
            process_list = [p.strip() for p in processes.split(',') if p.strip()]
            

            # 检查重复名称
            existing_names = [p['name'] for p in self.config.get_programs()]
            if name in existing_names:
                messagebox.showwarning("警告", "该程序名称已存在，请使用其他名称")
                return
            
            if time_limit:
                self.config.add_program(name, path, time_limit, process_list)
            self.load_programs()

    def remove_program(self):
        selected = self.tree.selection()
        if selected:
            self.config.remove_program(int(selected[0]))
            self.load_programs()



    def _verify_password(self):
        password = simpledialog.askstring("密码验证", "请输入授权密码:", show='*')
        if password != '012':
            messagebox.showerror("错误", "密码验证失败")
            return False
        return True

    def on_close(self):
        self.root.destroy()
        self.main_root.deiconify()


class StartupWindow:
    def __init__(self):
     
        self.root = tk.Tk()
        self.root.tk.call('encoding', 'system', 'utf-8')
        self.root.title("游戏启动平台 v1.3")
        self.root.protocol('WM_DELETE_WINDOW', self._on_close)
        self.root.resizable(False, False)
        # 加载主题资源
        self.bg_image = ImageTk.PhotoImage(Image.open(get_resource_path("backgrounds/pvz_bg.png")))
        self.btn_normal = ImageTk.PhotoImage(Image.open(get_resource_path("buttons/btn_normal.png")))
        self.btn_hover = ImageTk.PhotoImage(Image.open(get_resource_path("buttons/btn_hover.png")))
        self.logger = setup_logger()
        # 创建画布背景
        self.canvas = tk.Canvas(self.root, width=1024, height=647)
        self.canvas.create_image(0, 0, image=self.bg_image, anchor=tk.NW)
        self.canvas.pack(fill='both', expand=True)
        self.running_processes = {}
        # 主界面容器
        self.main_frame = tk.Frame(self.canvas, bg='')
        self.canvas.create_window((500, 300), window=self.main_frame, anchor=tk.CENTER)
        # 背景颜色设为白色
        self.main_frame.config(bg='#ffffff')
        self.config = ConfigManager()
        self._create_widgets()

    def _create_widgets(self):
        main_frame = ttk.Frame(self.root)
        main_frame.pack(padx=10, pady=10, fill='both')

        # 程序按钮区域
        btn_frame = ttk.LabelFrame(main_frame, text="快捷启动")
        btn_frame.pack(fill='both', expand=True)

        # 动态生成带样式的程序按钮
        programs = self.config.get_programs()
        for idx, program in enumerate(programs):
            btn = tk.Button(self.main_frame, 
                          image=self.btn_normal,
                          compound=tk.CENTER,
                          text=program['name'],
                          fg='#2d5c0f',
                          font=('微软雅黑', 12), 
                          relief=tk.FLAT,
                          bd=0,
                          activebackground='#a8d672',
                          command=lambda p=program: self._start_program(p))
            btn.config(highlightthickness=0)
            btn.bind('<Enter>', lambda e, b=btn: b.config(image=self.btn_hover))
            btn.bind('<Leave>', lambda e, b=btn: b.config(image=self.btn_normal))
            btn.grid(row=idx//3, column=idx%3, padx=15, pady=15)

        # 底部按钮容器
        bottom_frame = ttk.Frame(main_frame)
        bottom_frame.pack(pady=10)
        # 增加时间显示标签
        self.time_label = ttk.Label(bottom_frame, text=self.get_formatted_time(),
                                    font=('微软雅黑', 16,"bold"),
                                    foreground='#2d5c0f')
        self.time_label.pack(side='left', padx=5)
        self.update_time()
        # 温馨提示标签
        ttk.Label(bottom_frame, text="游戏好玩，作业也记得完成哦~", 
                 font=('微软雅黑', 16,"bold"), 
                 foreground='#2d5c0f').pack(side='left', padx=5)
        
        # 配置按钮
        ttk.Button(bottom_frame, text="配置", command=self._open_config).pack(side='left', padx=5)

    def get_formatted_time(self):
        return time.strftime('%Y-%m-%d %H:%M:%S')

    def update_time(self):
        self.time_label.config(text=self.get_formatted_time())
        self.root.after(1000, self.update_time)

    def _start_program(self, program):
        today = time.strftime('%Y-%m-%d')
        
        # 全局首次启动检查
        if self.config.config.get('last_launch_date') != today:
            self.config.config['last_launch_date'] = today
            self.config.save_config()
        else:
            # 生成密码规则
            current_day = time.strftime('%d').lstrip('0')
            current_hour = time.strftime('%H').lstrip('0')
            password = simpledialog.askstring("动态密码验证", 
                f"请输入8位数字密码：",
                show='*')
                
            if not (password and len(password) == 8 and password.isdigit() 
                    and current_day in password.lstrip('0') 
                    and current_hour in password.lstrip('0')):
                messagebox.showerror("错误", "密码验证失败")
                return

        try:
            self.root.iconify()
            time.sleep(1)
            self.logger.info(f"启动程序: {program['path']}")
            process = subprocess.Popen(program['path'])
            self.running_processes[process.pid] = {'start_time': time.time(), 'time_limit': program['time_limit'] * 60}
            Thread(target=self._monitor_process, args=(process, program)).start()
            # 更新全局启动时间
            self.config.config['last_launch_date'] = today
            self.config.save_config()
        except Exception as e:
            self.logger.error(f"启动失败: {str(e)}")
            messagebox.showerror("错误", f"启动失败: {str(e)}")

    def _monitor_process(self, process, program):
        self.logger.info(f"开始监控进程: {process.pid}，路径: {process.args}")
        start_time = time.time()
        time_limit = program['time_limit'] * 60
        has_warned = False
        while True:
            elapsed = time.time() - start_time
            remaining = time_limit - elapsed
            if remaining <= 120 and not has_warned:
                self.root.wm_attributes('-topmost', 1)
                self.root.after(0, lambda: messagebox.showwarning("即将超时", "还剩2分钟，请及时保存游戏进度！", parent=self.root))
                self.root.after(100, lambda: self.root.wm_attributes('-topmost', 0))
                has_warned = True
            if elapsed > time_limit:
                self.logger.warning(f"进程 {process.pid} 超时，正在终止...")
                if process.poll() is None:
                    subprocess.call(['taskkill', '/F', '/T', '/PID', str(process.pid)], creationflags=subprocess.CREATE_NO_WINDOW)
                # 终止关联进程
                for proc in psutil.process_iter(['name']):
                    if proc.info['name'] in program['terminate_processes']:
                        try:
                            proc.terminate()
                            self.logger.info(f"已终止关联进程: {proc.info['name']}")
                        except Exception as e:
                            self.logger.error(f"终止进程失败: {proc.info['name']} {str(e)}")
                self.root.after(0, lambda: messagebox.showwarning("超时", "已经玩了这么久了，快休息一下吧~"))
                break
            time.sleep(1)
        if process.pid in self.running_processes:
            del self.running_processes[process.pid]
            self.logger.info(f"进程 {process.pid} 监控结束")
            self.logger.info(f"进程 {process.pid} 已退出")
            time.sleep(1)

    def _open_config(self):
        password = simpledialog.askstring("密码验证", "请输入配置密码:", show='*')
        if password == '012':
            self.root.withdraw()
            config_app = TimeControlApp(self.root)
            config_app.root.mainloop()
        else:
            messagebox.showerror("错误", "密码错误")

    def _on_close(self):
        password = simpledialog.askstring("关闭验证", "请输入关闭密码:", show='*')
        if password == '012':
            # 终止所有正在运行的进程
            for pid in list(self.running_processes.keys()):
                try:
                    process = psutil.Process(pid)
                    if process.is_running():
                        process.terminate()  # 尝试正常终止进程
                        process.wait(timeout=2)  # 等待进程终止
                        if process.is_running():
                            process.kill()  # 如果进程仍在运行，强制终止
                except psutil.NoSuchProcess:
                    pass
                except psutil.TimeoutExpired:
                    process.kill()  # 超时后强制终止
                except Exception as e:
                    self.logger.error(f"终止进程 {pid} 失败: {str(e)}")
            self.root.destroy()
        else:
            messagebox.showerror("错误", "密码错误，程序将继续运行")


def is_already_running():
    current_process = psutil.Process()
    for proc in psutil.process_iter(['pid', 'name']):
        if proc.info['name'] == 'timecontrol.exe' and proc.info['pid'] != current_process.pid:
            return True
    return False

def bring_to_front(window_title):
    try:
        windows = gw.getWindowsWithTitle(window_title)
        if windows:
            window = windows[0]
            window.activate()
            window.maximize()
            window.restore()
            window.moveTo(0, 0)
    except IndexError:
        pass

def main():
    if is_already_running():
        bring_to_front("游戏启动平台 v1.3")
    else:
        startup = StartupWindow()
        startup.root.mainloop()

if __name__ == "__main__":
    main()
